(in-package :minipar)

(defparameter *minipar-path* nil)
(defparameter *minipar-process* nil)

;; TODO: Does not work the first time, but works after that (too much output from minipar)
;; TODO: Does not handle periods, due to use of read. Need to strip them first
;; TODO: Should not use pretty print in format of read parse

;; ROS Node

(defun minipar-node ()
  (with-ros-node ("minipar" :spin t)
    (start-minipar-process)
    (register-service "parse_with_minipar" 'Parse))
  (close-minipar-process)
  (format t "MINIPAR closed cleanly.~%"))
    
(def-service-callback Parse (sentence)
  (make-response :parse (format nil "~a" (parse-with-minipar sentence))))

;; Interacting with MINIPAR through an external process

(defun get-minipar-path ()
  (if (null *minipar-path*)
      (let ((proc (sb-ext:run-program "rospack" '("find" "minipar") :wait t :output :stream :search t)))
        (setf *minipar-path* (concatenate 'string
                                          (read-line (sb-ext:process-output proc))
                                          "/minipar/"))))
  *minipar-path*)

(defun start-minipar-process ()
  (setf *minipar-process* (sb-ext:run-program 
                           (concatenate 'string (get-minipar-path) "pdemo/pdemo") 
                           (list "-i" "-p" (concatenate 'string (get-minipar-path) "data"))
                           :wait nil 
                           :input :stream
                           :output :stream))
  ;; This is to flush out the warning lines that minipar prints
  (read-line (sb-ext:process-output *minipar-process*) nil nil)
  (read-line (sb-ext:process-output *minipar-process*) nil nil)
  ;(clear-output (sb-ext:process-output *minipar-process*))
  *minipar-process*)


(defun close-minipar-process ()
  (if *minipar-process*
      (sb-ext:process-close *minipar-process*)
      (sb-ext:process-kill *minipar-process* 2))
  (setf *minipar-process* nil))

(defun parse-with-minipar (sentence)
  (format t "PARSING: ~a~%" sentence)
  (write-line sentence (sb-ext:process-input *minipar-process*))
  (finish-output (sb-ext:process-input *minipar-process*))
  (read (sb-ext:process-output *minipar-process*)))